package com.ln.design.mode.behavior.command;

/**
 * 命令模式
 * <p>
 * 将一个请求封装成一个对象，从而让你使用不同的请求把客户端参数化，对请求排队或者记录请求日志，可以提供命令的撤销和恢复功能。
 * 角色：调用类，名另类，接收类
 * 接收类对操作进行最简单的封装
 * 命令类对这些基本操作进行二次封装，与接收类是组合关系
 * 调用类，与命令类组合关系
 *
 * @Author zhangj
 * @Date 2022/12/3 14:31
 */
public class CommandMode {

    /**
     * 抽象命令类
     */
    static abstract class Command {

        public abstract void execute();
    }

    /**
     * 接收者，负责接收命令并且执行命令
     */
    static class Receiver {
        public void doSomething() {
            System.out.println("接受者-业务逻辑处理");
        }
    }

    /**
     * 调用者，负责调用命令
     */
    static class Invoker {
        private Command command;

        public void setCommand(Command command) {
            this.command = command;
        }

        public void action() {
            this.command.execute();
        }
    }

    /**
     * 具体命令类
     */
    static class ConcreteCommand extends Command {
        private Receiver receiver;

        public ConcreteCommand(Receiver receiver) {
            this.receiver = receiver;
        }

        @Override
        public void execute() {
            //...二次封装处理
            this.receiver.doSomething();
        }
    }

    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Command command = new ConcreteCommand(receiver);
        command.execute();

        //客户端通过调用者来执行命令
        Invoker invoker = new Invoker();
        invoker.setCommand(command);
        invoker.action();
    }

}
